package cn.lngaosu.lwyd.module.integration.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.io.IOUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @author 张恒
 * <p>描述: 微博工具类
 * <p>日期: 2025/6/25 10:59
 */
public class WeiboUtil {

    private static final String LOGIN_URL = "https://weibo.com/login.php";
    private static final String LOGIN_ACTION_URL = "https://weibo.com/sso/login.php";
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
    private static Map<String, String> cookies = new HashMap<>();


    private static HttpClient client = HttpClients.createDefault();
    private static HttpResponse response = null;
    private static HttpGet httpGet = null;
    private static HttpEntity entity = null;

    private static ScriptEngineManager sem = new ScriptEngineManager();
    private static ScriptEngine se = sem.getEngineByName("javascript");
    private static String getJS() {
        try {
            return IOUtils.toString(new ClassPathResource("/js/weibo.js").getInputStream(), "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    static {
        try {
            String js = getJS();
            se.eval(js);
        } catch (ScriptException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 获取加密后的用户名
     *
     * @return
     */
    public static String getSu(String userId) {
        Invocable inv = (Invocable) se;
        try {
            return (String) inv.invokeFunction("getUs", userId);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 登录， 传入加密的用户名
     *
     * @param su
     * @return
     */
    public static JSONObject login(String su, String url, String redirectURI, String userId, String passwd, String clientId) {
        try {
            // 访问登录页面获取初始cookie
            sendGetRequest(LOGIN_URL);

            // 准备登录参数
            Map<String, String> loginParams = new HashMap<>();
            loginParams.put("username", userId);
            loginParams.put("password", passwd);
            loginParams.put("remember", "on");
            loginParams.put("backURL", "https://weibo.com/");
            loginParams.put("backTitle", "微博");
            loginParams.put("tryCount", "");
            loginParams.put("submit", "登录");

            // 发送登录请求
            String response = sendPostRequest(LOGIN_ACTION_URL, loginParams);

            // 检查登录是否成功
            if (response.contains("欢迎")) {
                System.out.println("登录成功！");
                // 登录成功后可以继续访问其他需要登录状态的页面
                String userPageResponse = sendGetRequest("https://weibo.com/u/your_user_id");
                System.out.println("用户页面内容: " + userPageResponse.substring(0, Math.min(200, userPageResponse.length())) + "...");
            } else {
                System.out.println("登录失败！");
                System.out.println("响应内容: " + response.substring(0, Math.min(200, response.length())) + "...");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取授权的token
     *
     * @param loginObj
     * @return
     */
    public static String getCode(JSONObject loginObj, String url, String redirectURI, String clientId) {
        // 授權登陸
        HttpPost postMethod = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<>();
        // 应用的App Key
        nvps.add(new BasicNameValuePair("client_id", clientId));
        // 应用的重定向页面
        nvps.add(new BasicNameValuePair("redirect_uri", redirectURI));
        // 模拟登录参数
        // 开发者或测试账号的用户名和密码
        nvps.add(new BasicNameValuePair("display", "default"));
        // 猜測是登陸的權證
        nvps.add(new BasicNameValuePair("ticket", loginObj.getString("ticket")));
        // nvps.add(new BasicNameValuePair("uid",
        // obj.getString("uid")));
        nvps.add(new BasicNameValuePair("regCallback", url + "?client_id=" + clientId
                + "&response_type=code&display=default&redirect_uri=" + redirectURI + "&from=&with_cookie="));
        nvps.add(new BasicNameValuePair("isLoginSina", "0"));
        nvps.add(new BasicNameValuePair("action", "login"));
        nvps.add(new BasicNameValuePair("withOfficalFlag", "0"));
        //nvps.add(new BasicNameValuePair("appkey62", appkey));
        postMethod.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
        // 添加头信息
        postMethod.setHeader("Referer", url);
        postMethod.setHeader("Host", "api.weibo.com");
        postMethod.setHeader("Origin", "https://api.weibo.com");
        postMethod.setHeader("Content-Type", "application/x-www-form-urlencoded");
        postMethod.setHeader("Upgrade-Insecure-Requests", "1");
        postMethod.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1;rv:11.0) Gecko/20100101 Firefox/11.0");

        // client = HttpClients.createDefault();
        response = null;
        try {
            response = client.execute(postMethod);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Header location = response.getFirstHeader("Location");
        if (location != null) {
            String retUrl = location.getValue();
            int begin = retUrl.indexOf("code=");
            if (begin != -1) {
                int end = retUrl.indexOf("&", begin);
                if (end == -1)
                    end = retUrl.length();
                String code = retUrl.substring(begin + 5, end);
                return code;
            }
        }
        return null;
    }

    private static String sendGetRequest(String url) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", USER_AGENT);
        addCookiesToRequest(connection);

        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            updateCookiesFromResponse(connection);
            return readResponse(connection);
        } else {
            return "GET请求失败，状态码: " + responseCode;
        }
    }

    private static String sendPostRequest(String url, Map<String, String> params) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("User-Agent", USER_AGENT);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        addCookiesToRequest(connection);
        connection.setDoOutput(true);

        // 构建POST参数
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String, String> param : params.entrySet()) {
            if (postData.length() != 0) postData.append('&');
            postData.append(URLEncoder.encode(param.getKey(), "utf-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(param.getValue(), "utf-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);

        // 发送POST数据
        try (OutputStream os = connection.getOutputStream()) {
            os.write(postDataBytes);
        }

        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            updateCookiesFromResponse(connection);
            return readResponse(connection);
        } else {
            return "POST请求失败，状态码: " + responseCode;
        }
    }

    private static void addCookiesToRequest(HttpURLConnection connection) {
        if (!cookies.isEmpty()) {
            StringBuilder cookieHeader = new StringBuilder();
            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
                if (cookieHeader.length() != 0) cookieHeader.append("; ");
                cookieHeader.append(cookie.getKey()).append("=").append(cookie.getValue());
            }
            connection.setRequestProperty("Cookie", cookieHeader.toString());
        }
    }

    private static void updateCookiesFromResponse(HttpURLConnection connection) {
        Map<String, String> newCookies = new HashMap<>();
        String headerName;
        for (int i = 1; (headerName = connection.getHeaderFieldKey(i)) != null; i++) {
            if (headerName.equals("Set-Cookie")) {
                String cookie = connection.getHeaderField(i);
                String[] parts = cookie.split(";")[0].split("=");
                if (parts.length >= 2) {
                    newCookies.put(parts[0], parts[1]);
                }
            }
        }
        cookies.putAll(newCookies);
    }

    private static String readResponse(HttpURLConnection connection) throws IOException {
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            return response.toString();
        }
    }
}
